package main

import (
	"flag"
	"fmt"
	"github.com/go-redis/redis"
	"go_19/client/DingTalk"
	"os"
	"strconv"
	"strings"
	"time"
)

var (
	GVA_REDIS   *redis.Client
	DingTalkUrl string
)

type RedisConf struct {
	Addr     string
	Password string
	DB       int
}

func main() {
	redis_host := flag.String("redisHost", "", "redis host")
	redis_pwd := flag.String("redisPwd", "", "redis password")
	redis_db := flag.Int("redisDb", 0, "redis db")
	queues := flag.String("queues", "", "monitor queues")
	alertLen := flag.Int64("alertLen", 100, "告警大小")
	dingTalk := flag.String("dingTalk", "https://oapi.dingtalk.com/robot/send?access_token=0c26150944daba9409ba6c4760bac0f4f5ed9b30ee5ca05eaa6698f8b6a2e9a8", "钉钉告警")
	flag.Parse()
	if *redis_host == "" {
		fmt.Println("请输入host1")
		os.Exit(0)
	}
	if *queues == "" {
		fmt.Println("请输入queue名称")
		os.Exit(0)
	}
	if *dingTalk == "" {
		fmt.Println("请输入钉钉告警链接")
		os.Exit(0)
	}
	DingTalkUrl = *dingTalk

	initRedis(RedisConf{
		*redis_host,
		*redis_pwd,
		*redis_db,
	})
	defer GVA_REDIS.Close()
	queueArr := strings.Split(*queues, ",")
	for _, queue := range queueArr {
		checkQueue(queue, *alertLen)
	}

}

func initRedis(redisCfg RedisConf) {
	client := redis.NewClient(&redis.Options{
		Addr:     redisCfg.Addr,
		Password: redisCfg.Password, // no password set
		DB:       redisCfg.DB,       // use default DB

		//连接池容量及闲置连接数量
		PoolSize:     15, // 连接池最大socket连接数，默认为4倍CPU数， 4 * runtime.NumCPU
		MinIdleConns: 10, //在启动阶段创建指定数量的Idle连接，并长期维持idle状态的连接数不少于指定数量；

		//超时
		DialTimeout:  5 * time.Second, //连接建立超时时间，默认5秒。
		ReadTimeout:  3 * time.Second, //读超时，默认3秒， -1表示取消读超时
		WriteTimeout: 3 * time.Second, //写超时，默认等于读超时
		PoolTimeout:  4 * time.Second, //当所有连接都处在繁忙状态时，客户端等待可用连接的最大等待时长，默认为读超时+1秒。

		//闲置连接检查包括IdleTimeout，MaxConnAge
		IdleCheckFrequency: 60 * time.Second, //闲置连接检查的周期，默认为1分钟，-1表示不做周期性检查，只在客户端获取连接时对闲置连接进行处理。
		IdleTimeout:        5 * time.Minute,  //闲置超时，默认5分钟，-1表示取消闲置超时检查
		MaxConnAge:         0 * time.Second,  //连接存活时长，从创建开始计时，超过指定时长则关闭连接，默认为0，即不关闭存活时长较长的连接

	})
	pong, err := client.Ping().Result()
	if err != nil {
		panic(err)
	} else {
		fmt.Println("-- redis ping:", pong, "(", client.Options().Addr, client.Options().DB, ")")
		GVA_REDIS = client
	}
}

func checkQueue(key string, alertLen int64) {
	lenSize := GVA_REDIS.LLen(key).Val()
	fmt.Println("key: ", key, "len: ", lenSize)
	if GVA_REDIS.LLen(key).Val() > alertLen {
		toAlert("queue_name:" + key + "\n" +
			"lenSize:" + strconv.FormatInt(lenSize, 10) + "\n" +
			"lenSize阈值:" + strconv.FormatInt(alertLen, 10))
	}
}

func toAlert(msg string) {
	alarmMsg :=
		"【REDIS LIST监控】" + "\n" +
			"SYSTEM_TIME:" + time.Now().Format("2006-01-02 15:04:05") + "\n" +
			"REDIS_HOST:" + GVA_REDIS.Options().Addr + "\n" +
			"DB:" + strconv.Itoa(GVA_REDIS.Options().DB) + "\n" +
			msg
	DingTalk.AlertToDingTalk(alarmMsg, DingTalkUrl)
}
